/*
 * @Author: cooper
 * @Date: 2025-06-08 22:51:14
 * @Wechat: cmd_develop
 * @Description: lcd触摸屏
 */
#include "bsp_lcd.h"
LCD_buffer LCD_Buffer;

/*LCD任务函数*/
TaskHandle_t lcd_handler;
TaskHandle_t stick_handler;
QueueHandle_t lcd_work_queue; // LCD工作邮箱
LCD_queue lcd_queue;          // LCD自创的队列
s16 ice_temp = 0;             // 冰柜的温度

u8 stick_moto_status = 0; // 签盒位置,0,1.09,19是移动中,0是原点,1是落签点。19是向落签点移动，09是向原点移动

/*************************************** 5号RS485——Modbus_Salve DMA配置 ***************************************/
/**
 * @brief  5号RS485——Modbus_DIO通讯串口DMA接收
 * @param  none
 * @retval none
 */
void LCD_USART_DMA_RX(void)
{
    /* 清除数据接收 */
    RX_LCD_BUFCLEAR();
    dma_init_type dma_init_struct;
    /* 使能时钟 */
    crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
    /* 使能dma复用功能 */
    dmamux_enable(DMA1, TRUE);
    /* 复位指定的 DMA 通道 */
    dma_reset(DMA1_CHANNEL5);
    /* 默认填充配置 */
    dma_default_para_init(&dma_init_struct);
    /* DMA 传输数据量+传输方向 */
    dma_init_struct.buffer_size = LCD_DATA_SIZE;
    dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
    /* 外设地址+数据宽度+地址增加模式 */
    dma_init_struct.peripheral_base_addr = (uint32_t)&UART7->dt;
    dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
    dma_init_struct.peripheral_inc_enable = FALSE;
    /* 存储器地址+数据宽度+地址增加模式 */
    dma_init_struct.memory_base_addr = (uint32_t)(&(RX_LCD(0)));
    dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
    dma_init_struct.memory_inc_enable = TRUE;
    /* 优先级+循环模式 */
    dma_init_struct.priority = DMA_PRIORITY_LOW;
    dma_init_struct.loop_mode_enable = FALSE;
    /* 初始化指定的 DMA 通道 */
    dma_init(DMA1_CHANNEL5, &dma_init_struct);
    /* 初始化dma复用功能 */
    dmamux_init(DMA1MUX_CHANNEL5, DMAMUX_DMAREQ_ID_UART7_RX);
    /* 使能指定通道 */
    dma_channel_enable(DMA1_CHANNEL5, TRUE);
}
/**
 * @brief  5号RS485——Modbus_DIO通讯串口DMA发送
 * @param  数据长度
 * @retval none
 */
void LCD_USART_DMA_TX(u8 size)
{
    dma_init_type dma_init_struct;
    /* 使能时钟 */
    crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
    /* 使能dma复用功能 */
    dmamux_enable(DMA1, TRUE);
    /* 复位指定的 DMA 通道 */
    dma_reset(DMA1_CHANNEL5);
    /* 默认填充配置 */
    dma_default_para_init(&dma_init_struct);
    /* DMA 传输数据量+传输方向 */
    dma_init_struct.buffer_size = size;
    dma_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL;
    /* 存储器地址+数据宽度+地址增加模式 */
    dma_init_struct.memory_base_addr = (uint32_t)(&(TX_LCD(0)));
    dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
    dma_init_struct.memory_inc_enable = TRUE;
    /* 外设地址+数据宽度+地址增加模式 */
    dma_init_struct.peripheral_base_addr = (uint32_t)&UART7->dt;
    dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
    dma_init_struct.peripheral_inc_enable = FALSE;
    /* 优先级+循环模式 */
    dma_init_struct.priority = DMA_PRIORITY_LOW;
    dma_init_struct.loop_mode_enable = FALSE;
    /* 使能DMA发送完成中断 */
    dma_interrupt_enable(DMA1_CHANNEL5, DMA_FDT_INT, TRUE);
    nvic_irq_enable(DMA1_Channel5_IRQn, 2, 2);
    /* 初始化指定的 DMA 通道 */
    dma_init(DMA1_CHANNEL5, &dma_init_struct);
    /* 初始化dma复用功能 */
    dmamux_init(DMA1MUX_CHANNEL5, DMAMUX_DMAREQ_ID_UART7_TX);
    /* 使能指定通道 */
    dma_channel_enable(DMA1_CHANNEL5, TRUE);
}
/**
 * @brief  5号RS485——Modbus_dio初始化
 * @param  none
 * @retval none
 */
void LCD_Init(void)
{
    gpio_init_type gpio_init_struct;
    /* 使能时钟 */
    crm_periph_clock_enable(CRM_UART7_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
    /* GPIO配置 */
    gpio_default_para_init(&gpio_init_struct);
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_pins = GPIO_PINS_3 | GPIO_PINS_4;
    gpio_init(GPIOB, &gpio_init_struct);
    /* 复用 */
    gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE3, GPIO_MUX_8);
    gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE4, GPIO_MUX_8);
    /* 串口参数 */
    usart_reset(UART7);
    usart_init(UART7, 9600, USART_DATA_8BITS, USART_STOP_1_BIT);
    usart_transmitter_enable(UART7, TRUE);
    usart_receiver_enable(UART7, TRUE);
    /* 中断配置 */
    nvic_irq_enable(UART7_IRQn, 2, 2);
    usart_interrupt_enable(UART7, USART_IDLE_INT, TRUE);
    /* 使用DMA */
    usart_dma_receiver_enable(UART7, TRUE);
    usart_dma_transmitter_enable(UART7, TRUE);
    /* 使能 */
    usart_enable(UART7, TRUE);
    /* DMA接收	*/
    LCD_USART_DMA_RX();
}
/**
 * @brief  Modbus_Salve串口7中断处理函数
 * @param  none
 * @retval none
 */
void UART7_IRQHandler(void)
{
    // 0状态
    u8 code[lcd_work_queue_array_num];
    code[0] = LCD_RX_CODE; // 从机转过来的数据，包括继电器/LCD/冰柜

    uint32_t ulReturn;
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    /* 进入临界段，临界段可以嵌套 */
    ulReturn = taskENTER_CRITICAL_FROM_ISR();
    if (usart_flag_get(UART7, USART_IDLEF_FLAG) != RESET)
    {
        dma_channel_enable(DMA1_CHANNEL5, FALSE);
        dma_flag_clear(DMA1_FDT5_FLAG);
        // 获取接收总数
        RX_LCD_TOTAL = LCD_DATA_SIZE - dma_data_number_get(DMA1_CHANNEL5);
        // 释放信号量
        xQueueSendFromISR(lcd_work_queue, &code, &xHigherPriorityTaskWoken);
        // 切换任务
        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
        usart_flag_clear(UART7, USART_IDLEF_FLAG);
    }
    /* 退出临界段 */
    taskEXIT_CRITICAL_FROM_ISR(ulReturn);
}

/**
 * @brief  Modbus_Salve串口DMA1通道5中断处理函数
 * @param  none
 * @retval none
 */
void DMA1_Channel5_IRQHandler(void)
{
    uint32_t ulReturn;
    /* 进入临界段，临界段可以嵌套 */
    ulReturn = taskENTER_CRITICAL_FROM_ISR();
    if (dma_interrupt_flag_get(DMA1_FDT5_FLAG))
    {
        LCD_USART_DMA_RX();
        dma_flag_clear(DMA1_FDT5_FLAG);
    }
    /* 退出临界段 */
    taskEXIT_CRITICAL_FROM_ISR(ulReturn);
}

/// @brief 签盒任务
/// @param pvParameters
void lcd_task_function(void *pvParameters)
{
    while (1)
    {
        vTaskDelay(pdMS_TO_TICKS(300));
    }
}

/// @brief LCD任务
/// @param
void LCD_TASK(void)
{
    // 创建签盒
    xTaskCreate((TaskFunction_t)lcd_task_function,
                (const char *)"lcd_TASK",
                (uint16_t)128, // 128
                (void *)NULL,
                (UBaseType_t)1,
                (TaskHandle_t *)&stick_handler);
}
